package cn.cqie.frame.service.impl;

import cn.cqie.frame.bo.query.QueryRoleBo;
import cn.cqie.frame.entity.RoleMenu;
import cn.cqie.frame.entity.SysRole;
import cn.cqie.frame.bo.add.AddPermissionsBo;
import cn.cqie.frame.bo.update.UpdatePermissionsBo;
import cn.cqie.frame.enums.YesOrNo;
import cn.cqie.frame.mapper.RoleMenuMapper;
import cn.cqie.frame.mapper.SysRoleMapper;
import cn.cqie.frame.service.RoleMenuService;
import cn.cqie.frame.service.SysRoleService;
import cn.cqie.frame.utils.AssertUtil;
import cn.cqie.frame.utils.BeanCopyUtils;
import cn.cqie.frame.utils.DateUtils;
import cn.cqie.frame.utils.MyPageHelper;
import cn.cqie.frame.vo.PermissionsVo;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XYHL
 * @since 2021-09-02
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    private  SysRoleService sysRoleService;
    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;

    /**
     * 分页查询权限信息
     * @param bo
     * @return
     */
    @Override
    public List<PermissionsVo> getPermissionsList(QueryRoleBo bo) {
        MyPageHelper.startPage(bo);
        LambdaQueryWrapper<SysRole> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getRoleName()!=null,SysRole::getRoleName,bo.getRoleName())
           .eq(SysRole::getStatus, YesOrNo.YES.getCode());
        List<SysRole> dataList = sysRoleService.list(lqw);
        return entity2Vo(dataList);
    }

    /**
     * 更新权限信息
     * @param bo
     * @return
     */
    @Override
    public Boolean updatePermissions(UpdatePermissionsBo bo) {
        LambdaUpdateWrapper<SysRole> lqw = new LambdaUpdateWrapper<>();
        lqw.set(SysRole::getRoleName,bo.getRoleName())
           .eq(SysRole::getId,bo.getId());
        int update = baseMapper.update(null,lqw);
        return update > 0;
    }

    /**
     * 插入权限和对应的菜单信息
     * @param bo
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void saveOrUpdateRole(AddPermissionsBo bo) {
        LocalDateTime sysTime = DateUtils.getLocalDateTime();
        SysRole sysRole = BeanCopyUtils.copyObject(bo,SysRole.class);
        sysRole.setCreateTime(sysTime);
        sysRole.setUpdateTime(sysTime);
        sysRole.setStatus(1);
        boolean b = this.saveOrUpdate(sysRole);
         if (CollectionUtils.isNotEmpty(bo.getMenuIdList())){
            if (Objects.nonNull(bo.getId())){
                roleMenuService.remove(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId,bo.getId()));
            }
            List<RoleMenu> roleMenuList = bo.getMenuIdList().stream()
                .map(menuId -> RoleMenu.builder()
                                        .roleId(sysRole.getId())
                                        .menuId(menuId)
                                        .build())
                 .collect(Collectors.toList());
              roleMenuService.saveBatch(roleMenuList);
        }
        AssertUtil.isTrue(b , "插入角色失败");

    }

    /**
     * 删除权限和对应的菜单的关联信息
     * @param roleId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public Boolean deletePermissions(Integer roleId) {
        LambdaQueryWrapper<SysRole> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysRole::getStatus, 1);
        lqw.in(SysRole::getId, roleId);
        List<SysRole> sysRoles = baseMapper.selectList(lqw);
        AssertUtil.isNotEmpty(sysRoles, "角色不存在");
        int update = baseMapper.update(null, new LambdaUpdateWrapper<SysRole>()
                .set(SysRole::getStatus, YesOrNo.NO.getCode())
                .set(SysRole::getUpdateTime, DateUtils.getLocalDateTime())
                .in(SysRole::getId, roleId));
        LambdaQueryWrapper<RoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(RoleMenu::getRoleId, roleId);
        int delete = roleMenuMapper.delete(lambdaQueryWrapper);
        return update > 0 && delete >0;
    }

    /**
     * 获取用户权限信息
     * @return
     */
    @Override
    public List<PermissionsVo> getUserPermissionsList() {
        LambdaQueryWrapper<SysRole> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysRole::getStatus, YesOrNo.YES.getCode());
        List<SysRole> dataList = sysRoleService.list(lqw);
        return entity2Vo(dataList);
    }

    /**
     * 格式转换
     * @param collection
     * @return
     */
    private List<PermissionsVo> entity2Vo(Collection<SysRole> collection) {
        List<PermissionsVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, PermissionsVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<SysRole> page = (Page<SysRole>) collection;
            Page<PermissionsVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

}
